package com.mineoj.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mineoj.common.ErrorCode;
import com.mineoj.exception.BusinessException;
import com.mineoj.model.entity.QuestionList;
import com.mineoj.model.entity.QuestionListFavour;
import com.mineoj.model.entity.QuestionListFavour;
import com.mineoj.model.entity.User;
import com.mineoj.service.QuestionListFavourService;
import com.mineoj.service.QuestionListService;
import com.mineoj.service.QuestionListFavourService;
import com.mineoj.mapper.QuestionListFavourMapper;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
* @author 明月
* @description 针对表【question_list_favour(题单收藏)】的数据库操作Service实现
* @createDate 2025-04-05 16:35:01
*/
@Service
public class QuestionListFavourServiceImpl extends ServiceImpl<QuestionListFavourMapper, QuestionListFavour>
    implements QuestionListFavourService{
    @Resource
    private QuestionListService questionListService;

    /**
     * 题单收藏
     *
     * @param questionListId
     * @param loginUser
     * @return
     */
    @Override
    public int doQuestionListFavour(long questionListId, User loginUser) {
        // 判断是否存在
        QuestionList questionList = questionListService.getById(questionListId);
        if (questionList == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        // 是否已题单收藏
        long userId = loginUser.getId();
        // 每个用户串行题单收藏
        // 锁必须要包裹住事务方法
        QuestionListFavourService questionListFavourService = (QuestionListFavourService) AopContext.currentProxy();
        synchronized (String.valueOf(userId).intern()) {
            return questionListFavourService.doQuestionListFavourInner(userId, questionListId);
        }
    }

    /**
     * 题单收藏分页
     * @param page
     * @param queryWrapper
     * @param favourUserId
     * @return
     */
    @Override
    public Page<QuestionList> listFavourQuestionListByPage(IPage<QuestionList> page, Wrapper<QuestionList> queryWrapper, long favourUserId) {
        if (favourUserId <= 0) {
            return new Page<>();
        }
        return baseMapper.listFavourQuestionListByPage(page, queryWrapper, favourUserId);
    }

    /**
     * 封装了事务的方法
     *
     * @param userId
     * @param questionListId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int doQuestionListFavourInner(long userId, long questionListId) {
        QuestionListFavour questionListFavour = new QuestionListFavour();
        questionListFavour.setUserId(userId);
        questionListFavour.setQuestionListId(questionListId);
        QueryWrapper<QuestionListFavour> questionListFavourQueryWrapper = new QueryWrapper<>(questionListFavour);
        QuestionListFavour oldQuestionListFavour = this.getOne(questionListFavourQueryWrapper);
        boolean result;
        // 已收藏
        if (oldQuestionListFavour != null) {
            result = this.remove(questionListFavourQueryWrapper);
            if (result) {
                // 题单收藏数 - 1
                result = questionListService.update()
                        .eq("id", questionListId)
                        .gt("favourNum", 0)
                        .setSql("favourNum = favourNum - 1")
                        .update();
                return result ? -1 : 0;
            } else {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }
        } else {
            // 未题单收藏
            result = this.save(questionListFavour);
            if (result) {
                // 题单收藏数 + 1
                result = questionListService.update()
                        .eq("id", questionListId)
                        .setSql("favourNum = favourNum + 1")
                        .update();
                return result ? 1 : 0;
            } else {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }
        }
    }
}




